package com.wennn.top.security.filter;

import com.wennn.top.common.vo.IResult;
import com.wennn.top.security.model.JwtAuthToken;
import com.wennn.top.security.model.SessionContext;
import com.wennn.top.security.model.token.JwtRawAccessToken;
import com.wennn.top.security.util.JwtUtil;
import com.wennn.top.security.util.SecurityConst;
import com.wennn.top.security.util.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 验证用户名密码正确后，生成一个token，并将token返回给客户端
 * 该类继承自UsernamePasswordAuthenticationFilter，重写了其中的2个方法
 * attemptAuthentication ：接收并解析用户凭证。
 * successfulAuthentication ：用户成功登录后，这个方法会被调用，我们在这个方法里生成token。
 *
 * @author wennn on 2020/5/7
 */
@Slf4j
public class JWTUsernamePasswordFilter extends UsernamePasswordAuthenticationFilter {


    public JWTUsernamePasswordFilter(AuthenticationManager authenticationManager) {
        super();
        this.setAuthenticationManager(authenticationManager);
    }

    // 接收并解析用户凭证
    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        return this.getAuthenticationManager().authenticate(new JwtAuthToken(username, password));
    }

    // 用户成功登录后，这个方法会被调用，我们在这个方法里生成token
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {
        if(log.isDebugEnabled()){
            log.debug("认证成功");
        }
        JwtAuthToken authToken = (JwtAuthToken) auth;
        try {
            JwtRawAccessToken jwtRawAccessToken = (JwtRawAccessToken) authToken.getCredentials();
            // 登录成功后，返回token到header里面
            response.addHeader(SecurityConst.AUTH_HEADER, JwtUtil.tokenToHeader(jwtRawAccessToken.getToken()));
        } catch (Exception e) {
            e.printStackTrace();
        }

        SessionContext sessionContext = (SessionContext) auth.getPrincipal();

        WebUtil.response(response,IResult.ok(sessionContext.getSessionUser()));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        if(log.isDebugEnabled()){
            log.debug("登陆失败");
        }
        response.addHeader(SecurityConst.AUTH_HEADER, "");
        WebUtil.response(response,IResult.fail("500", failed.getMessage()));
    }



}
